package com.yixing.tech.system.service.impl;

import com.yixing.tech.common.base.BaseMongoDao;
import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.common.base.Page;
import com.yixing.tech.common.base.PageRow;
import com.yixing.tech.common.enums.ErrCode;
import com.yixing.tech.common.enums.YesOrNo;
import com.yixing.tech.system.po.UserGroup;
import com.yixing.tech.system.service.IUserGroupService;
import com.yixing.tech.common.utils.CommonUtil;
import com.yixing.tech.common.utils.DataUtil;
import com.yixing.tech.common.vo.s3.UserGroupVO;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yixing tech
 * at 2022/3/31
 * describe：
 */
@Service
public class UserGroupServiceImpl implements IUserGroupService {

    @Resource
    private BaseMongoDao baseMongoDao;
    @Resource
    private MongoTemplate mongoTemplate;


    @Override
    public void add(UserGroupVO userGroup) throws BusinessException {
        UserGroupVO condition = new UserGroupVO();
        condition.setName(userGroup.getName());
        condition.setTenantId(userGroup.getTenantId());
        if (baseMongoDao.exists(condition, UserGroup.class)) {
            throw new BusinessException(ErrCode.USERGROUP_EXISTED);
        }
        UserGroup u = DataUtil.o2o(userGroup, UserGroup.class);
        u.setId(null);
        baseMongoDao.save(u);
    }

    @Override
    public void batchAdd(List<UserGroupVO> list) throws BusinessException {

    }

    @Override
    public UserGroupVO queryById(String id) {

        Criteria criteria = Criteria.where("_id").is(new ObjectId(id));
        LookupOperation lookup = Aggregation.lookup("user", "users._id", "_id", "users");
        ProjectionOperation project = Aggregation.project("name", "users");
        Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria), lookup, project);
        AggregationResults<UserGroupVO> results = mongoTemplate.aggregate(agg, "userGroup", UserGroupVO.class);
        UserGroupVO vo = results.getMappedResults().get(0);
        vo.getUsers().forEach(m -> m.setPassword(null));
        return vo;

    }

    @Override
    public List<UserGroupVO> queryByIds(List<String> ids) {
        return null;
    }

    @Override
    public UserGroupVO queryByCondition(UserGroupVO userGroupVO) throws BusinessException {
        return null;
    }

    @Override
    public void update(UserGroupVO userGroup) throws BusinessException {
        baseMongoDao.update(DataUtil.o2o(userGroup, UserGroup.class));
    }

    @Override
    public Page<UserGroupVO> list(PageRow<UserGroupVO> pageRow) {
        Criteria criteria = baseMongoDao.condition2Criteria(pageRow.getCondition());
        LookupOperation lookup = Aggregation.lookup("user", "users._id", "_id", "users");
        ProjectionOperation project = Aggregation.project("name", "users");

        SkipOperation skip = Aggregation.skip(Long.valueOf(pageRow.getPageNo() * pageRow.getPageSize()));
        LimitOperation limit = Aggregation.limit(pageRow.getPageSize());
        Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria), skip, limit, lookup, project);
        AggregationResults<UserGroup> results = mongoTemplate.aggregate(agg, "userGroup", UserGroup.class);
        List<UserGroup> list = results.getMappedResults();
        List<UserGroupVO> vos = list.stream().map(m -> {
                    if (!CommonUtil.listIsBlank(m.getUsers())) {
                        m.getUsers().forEach(u -> u.setPassword(null));
                    }
                    return DataUtil.o2o(m, UserGroupVO.class);
                }
        ).collect(Collectors.toList());
        long count = mongoTemplate.count(Query.query(criteria), UserGroup.class);

        return new Page<>(vos, pageRow.getPageSize(), pageRow.getPageNo() + 1, count);
    }

    @Override
    public List<UserGroupVO> list(UserGroupVO condition) {
        Criteria criteria = baseMongoDao.condition2Criteria(condition);
        LookupOperation lookup = Aggregation.lookup("user", "users._id", "_id", "users");
        ProjectionOperation project = Aggregation.project("name", "users");
        Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria), lookup, project);
        AggregationResults<UserGroup> results = mongoTemplate.aggregate(agg, "userGroup", UserGroup.class);
        List<UserGroup> list = results.getMappedResults();
        return list.stream().map(m -> {
                    if (!CommonUtil.listIsBlank(m.getUsers())) {
                        m.getUsers().forEach(u -> u.setPassword(null));
                    }
                    return DataUtil.o2o(m, UserGroupVO.class);
                }
        ).collect(Collectors.toList());
    }

    @Override
    public void deleteById(String id) throws BusinessException {
        UserGroup o = new UserGroup();
        o.setId(id);
        o.setIsDelete(YesOrNo.YES.ordinal());
        baseMongoDao.update(o);
    }

    @Override
    public void delete(List<String> ids) throws BusinessException {

    }
}
